<script setup lang="ts">
import { ref, reactive, watch, onMounted } from "vue";
import type { FormInstance } from "element-plus";
import { Search, Refresh, Download } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { getLogList, exportLog, clearLog } from "@/api/log";

interface LogRecord {
  id: string;
  storeId: string;
  title: string;
  businessType: string;
  operName: string;
  operUrl: string;
  operIp: string;
  operParam: string;
  jsonResult: string;
  status: number;
  errorMsg: string;
  operTime: string;
}

// 搜索表单
const searchForm = reactive({
  title: "",
  operName: "",
  businessType: "",
  dateRange: [],
  status: undefined
});

// 表格数据
const tableData = ref<LogRecord[]>([]);
const loading = ref(false);
const total = ref(0);

// 分页配置
const pagination = reactive({
  currentPage: 1,
  pageSize: 10
});

// 业务类型选项
const businessTypes = [
  { label: "全部", value: "" },
  { label: "新增", value: "INSERT" },
  { label: "修改", value: "UPDATE" },
  { label: "删除", value: "DELETE" },
  { label: "查询", value: "SELECT" },
  { label: "其他", value: "OTHER" }
];

// 状态选项
const statusOptions = [
  { label: "全部", value: undefined },
  { label: "成功", value: 0 },
  { label: "失败", value: 1 }
];

// 查看详情对话框
const detailVisible = ref(false);
const currentLog = ref<LogRecord | null>(null);

// 格式化JSON显示
const formatJson = (json: string) => {
  try {
    return JSON.stringify(JSON.parse(json), null, 2);
  } catch {
    return json;
  }
};

// 获取状态标签类型
const getStatusType = (status: number) => {
  return status === 0 ? "success" : "danger";
};

// 获取状态文本
const getStatusText = (status: number) => {
  return status === 0 ? "成功" : "失败";
};

// 获取日志列表数据
const fetchLogData = async () => {
  loading.value = true;
  try {
    // 准备查询参数
    const params: any = {
      title: searchForm.title || undefined,
      operName: searchForm.operName || undefined,
      businessType: searchForm.businessType || undefined,
      status: searchForm.status
    };

    // 添加日期范围
    if (searchForm.dateRange && searchForm.dateRange.length === 2) {
      params.beginDateTime = searchForm.dateRange[0] + " 00:00:00";
      params.endDateTime = searchForm.dateRange[1] + " 23:59:59";
    }

    try {
      const res = await getLogList(
        pagination.currentPage,
        pagination.pageSize,
        params
      );
      // 使用类型断言处理响应
      const response = res as any;
      if (response.code === 200) {
        tableData.value = response.data.result || [];
        total.value = response.data.total || 0;
      } else {
        ElMessage.error(response.message || "获取日志列表失败");
      }
    } catch (e) {
      console.error("API请求失败", e);
      ElMessage.error("获取日志列表失败");
    }
  } catch (error) {
    console.error("获取日志数据出错", error);
    ElMessage.error("获取日志数据出错");
  } finally {
    loading.value = false;
  }
};

// 处理搜索
const handleSearch = () => {
  pagination.currentPage = 1;
  fetchLogData();
};

// 处理重置
const handleReset = (formEl: FormInstance | undefined) => {
  if (!formEl) return;
  formEl.resetFields();
  handleSearch();
};

// 查看详情
const handleViewDetail = (row: LogRecord) => {
  currentLog.value = row;
  detailVisible.value = true;
};

// 处理导出
const handleExport = async () => {
  try {
    loading.value = true;
    ElMessage.info("正在导出数据，请稍候...");

    // 准备查询参数
    const params: any = {
      title: searchForm.title || undefined,
      operName: searchForm.operName || undefined,
      businessType: searchForm.businessType || undefined,
      status: searchForm.status
    };

    // 添加日期范围
    if (searchForm.dateRange && searchForm.dateRange.length === 2) {
      params.beginDateTime = searchForm.dateRange[0] + " 00:00:00";
      params.endDateTime = searchForm.dateRange[1] + " 23:59:59";
    }

    // 调用导出API，使用类型断言
    const res = (await exportLog(params)) as any;

    // 创建Blob对象并下载
    const blob = new Blob([res], { type: "application/vnd.ms-excel" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `系统日志_${new Date().getTime()}.xlsx`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);

    ElMessage.success("导出成功");
  } catch (error) {
    console.error("导出失败", error);
    ElMessage.error("导出失败");
  } finally {
    loading.value = false;
  }
};

// 清空日志
const handleClearLog = () => {
  ElMessageBox.confirm("确定要清空所有日志吗？这个操作不可恢复！", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning"
  })
    .then(async () => {
      try {
        loading.value = true;
        const res = (await clearLog()) as any;
        if (res.code === 200) {
          ElMessage.success("日志清空成功");
          fetchLogData();
        } else {
          ElMessage.error(res.message || "清空日志失败");
        }
      } catch (error) {
        console.error("清空日志出错", error);
        ElMessage.error("清空日志出错");
      } finally {
        loading.value = false;
      }
    })
    .catch(() => {});
};

// 处理页码变化
const handleCurrentChange = (val: number) => {
  pagination.currentPage = val;
  fetchLogData();
};

// 处理每页数量变化
const handleSizeChange = (val: number) => {
  pagination.pageSize = val;
  pagination.currentPage = 1;
  fetchLogData();
};

// 监听分页变化
watch([() => pagination.currentPage, () => pagination.pageSize], () => {
  fetchLogData();
});

// 页面加载时获取数据
onMounted(() => {
  fetchLogData();
});
</script>

<template>
  <div class="log-record-container">
    <el-card class="search-card">
      <el-form ref="searchFormRef" :model="searchForm" inline>
        <el-form-item label="操作标题" prop="title">
          <el-input
            v-model="searchForm.title"
            placeholder="请输入操作标题"
            clearable
          />
        </el-form-item>
        <el-form-item label="操作人员" prop="operName">
          <el-input
            v-model="searchForm.operName"
            placeholder="请输入操作人员"
            clearable
          />
        </el-form-item>
        <el-form-item label="业务类型" style="width: 250px" prop="businessType">
          <el-select
            v-model="searchForm.businessType"
            placeholder="请选择业务类型"
            clearable
          >
            <el-option
              v-for="item in businessTypes"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="操作状态" style="width: 250px" prop="status">
          <el-select
            v-model="searchForm.status"
            placeholder="请选择状态"
            clearable
          >
            <el-option
              v-for="item in statusOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="操作时间" prop="dateRange">
          <el-date-picker
            v-model="searchForm.dateRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :icon="Search" @click="handleSearch"
            >搜索</el-button
          >
          <el-button :icon="Refresh" @click="handleReset(searchFormRef)"
            >重置</el-button
          >
        </el-form-item>
      </el-form>
    </el-card>

    <el-card class="log-table-card">
      <template #header>
        <div class="card-header">
          <span class="title">操作日志列表</span>
          <div class="button-group">
            <el-button type="success" :icon="Download" @click="handleExport"
              >导出</el-button
            >
            <el-button type="danger" @click="handleClearLog">清空</el-button>
          </div>
        </div>
      </template>

      <el-table
        v-loading="loading"
        :data="tableData"
        border
        style="width: 100%"
      >
        <el-table-column type="index" width="50" label="#" align="center" />
        <el-table-column
          prop="id"
          label="日志编号"
          width="100"
          align="center"
        />
        <el-table-column
          prop="title"
          label="操作标题"
          min-width="150"
          show-overflow-tooltip
        />
        <el-table-column
          prop="businessType"
          label="业务类型"
          width="100"
          align="center"
        >
          <template #default="{ row }">
            <el-tag
              :type="
                row.businessType === 'INSERT'
                  ? 'success'
                  : row.businessType === 'UPDATE'
                    ? 'warning'
                    : row.businessType === 'DELETE'
                      ? 'danger'
                      : row.businessType === 'SELECT'
                        ? 'info'
                        : 'default'
              "
            >
              {{
                row.businessType === "INSERT"
                  ? "新增"
                  : row.businessType === "UPDATE"
                    ? "修改"
                    : row.businessType === "DELETE"
                      ? "删除"
                      : row.businessType === "SELECT"
                        ? "查询"
                        : "其他"
              }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="operName"
          label="操作人员"
          width="120"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="operIp"
          label="操作IP"
          width="150"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column
          prop="operUrl"
          label="请求地址"
          min-width="150"
          show-overflow-tooltip
        />
        <el-table-column prop="status" label="状态" width="80" align="center">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)">{{
              getStatusText(row.status)
            }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column
          prop="operTime"
          label="操作时间"
          width="180"
          align="center"
          show-overflow-tooltip
        />
        <el-table-column label="操作" width="100" align="center" fixed="right">
          <template #default="{ row }">
            <el-button link type="primary" @click="handleViewDetail(row)"
              >详情</el-button
            >
          </template>
        </el-table-column>
      </el-table>

      <div class="pagination">
        <el-pagination
          v-model:current-page="pagination.currentPage"
          v-model:page-size="pagination.pageSize"
          background
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          :page-sizes="[10, 20, 50, 100]"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 详情对话框 -->
    <el-dialog v-model="detailVisible" title="日志详情" width="750px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="日志编号">{{
          currentLog?.id
        }}</el-descriptions-item>
        <el-descriptions-item label="操作人员">{{
          currentLog?.operName
        }}</el-descriptions-item>
        <el-descriptions-item label="操作标题">{{
          currentLog?.title
        }}</el-descriptions-item>
        <el-descriptions-item label="业务类型">{{
          currentLog?.businessType
        }}</el-descriptions-item>
        <el-descriptions-item label="操作IP">{{
          currentLog?.operIp
        }}</el-descriptions-item>
        <el-descriptions-item label="操作状态">
          <el-tag :type="currentLog?.status === 0 ? 'success' : 'danger'">
            {{ currentLog?.status === 0 ? "成功" : "失败" }}
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="操作时间">{{
          currentLog?.operTime
        }}</el-descriptions-item>
        <el-descriptions-item label="请求地址">{{
          currentLog?.operUrl
        }}</el-descriptions-item>
        <el-descriptions-item label="请求参数" :span="2">
          <div class="code-block">
            <pre>{{ formatJson(currentLog?.operParam || "{}") }}</pre>
          </div>
        </el-descriptions-item>
        <el-descriptions-item label="返回结果" :span="2">
          <div class="code-block">
            <pre>{{ formatJson(currentLog?.jsonResult || "{}") }}</pre>
          </div>
        </el-descriptions-item>
        <el-descriptions-item
          v-if="currentLog?.errorMsg"
          label="错误消息"
          :span="2"
        >
          <div class="code-block">
            <pre>{{ currentLog?.errorMsg }}</pre>
          </div>
        </el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="detailVisible = false">关闭</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.log-record-container {
  padding: 15px;
}

.search-card {
  margin-bottom: 15px;
}

.log-table-card {
  margin-bottom: 15px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.title {
  font-size: 16px;
  font-weight: bold;
}

.pagination {
  margin-top: 15px;
  display: flex;
  justify-content: flex-end;
}

.code-block {
  background-color: #f8f8f8;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  padding: 10px;
  max-height: 200px;
  overflow: auto;
}

.code-block pre {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
}
</style>
